package com.itheima.vms.utils;

import javax.crypto.Cipher;
import java.security.*;

/**
 * 【非对称加密算法】
 *      【2个秘钥】
 *          公钥：加密
 *          私钥：解密
 * RSA（Rivest-Shamir-Adleman）是一种非对称加密算法，它使用一对密钥（公钥和私钥）来进行加密和解密操作。RSA算法的安全性基于大整数分解的困难性，即通过已知的公钥无法轻易计算出私钥，从而实现了安全的加密和解密过程。
 * 在RSA算法中，公钥用于加密数据，私钥用于解密数据。加密过程将明文数据通过公钥进行加密，得到密文数据；解密过程则使用私钥对密文数据进行解密，还原出原始的明文数据。RSA算法也常用于数字签名和密钥交换等安全通信场景中。
 * RSA算法的安全性和实用性使其成为了广泛使用的加密算法之一，被应用于网络通信、数据传输、数字签名、身份认证等领域。
 */
public class RSAUtil {

    public static void main(String[] args) throws Exception {
        // 1. 生成RSA密钥对
        KeyPair keyPair = generateRSAKeyPair();

        // 2. 获取公钥和私钥
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 3. 明文
        String plainText = "123456";

        // 4. 使用公钥加密明文
        byte[] encryptedText = encrypt(plainText, publicKey);

        // 5. 使用私钥解密密文
        String decryptedText = decrypt(encryptedText, privateKey);

        // 6. 输出结果
        System.out.println("原始明文: " + plainText);
        System.out.println("加密后的密文: " + new String(encryptedText));
        System.out.println("解密后的明文: " + decryptedText);
    }

    /***
     * 生成RSA密钥对
     *      公钥+私钥
     * @return
     * @throws Exception
     */
    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        SecureRandom secureRandom = new SecureRandom();
        keyPairGenerator.initialize(2048, secureRandom);
        return keyPairGenerator.generateKeyPair();
    }

    // 使用公钥加密明文
    public static byte[] encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(plainText.getBytes());
    }

    // 使用私钥解密密文
    public static String decrypt(byte[] encryptedText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedText);
        return new String(decryptedBytes);
    }
}